
'''
生成验证码
1、准备素材
字体ttf 文字内容 颜色  干扰线
2、画验证码
pip install Pillow、random
创建图片
记录文字内容  django-session
3、 io文件流
BytesIO
'''
import io
import os

from PIL import ImageDraw, Image, ImageFont

from django.conf import settings
from django.http import HttpResponse

from django.utils.crypto import random


class VerifyCode(object):
    '''验证码类'''

    def __init__(self, dj_request):
        # 验证码图片尺寸
        self.code_len = 4
        self.dj_request = dj_request
        self.img_width = 100
        self.img_height = 30
        # django中session名称
        self.session_key = 'verify_code'

    def gen_code(self):
        '''生成验证码'''
        # 使用随机数生成验证码字符串
        code = self._get_vcode()
        # 把验证码存在session中
        self.dj_request.session[self.session_key] = code
        # 准备随机元素(背景颜色，验证码文字颜色、干扰线)
        font_color = ['black', 'darkblue', 'darkred', 'brown', 'green', 'red']
        # RGB随机背景色
        bg_color = (random.randrange(230, 255), random.randrange(230, 255), random.randrange(230, 255))
        # 字体路径
        font_path = os.path.join(settings.BASE_DIR, 'static', 'font', 'timesbi.ttf')

        # 创建图片
        # 获得画布  北京
        im = Image.new('RGB', (self.img_width, self.img_height), bg_color)
        # 获得画笔
        draw = ImageDraw.Draw(im)

        # 画干扰线

        # 随机条数干扰线
        for i in range(random.randrange(1, int(self.code_len / 2) + 1)):
            # 线条的颜色
            line_color = random.choice(font_color)
            # 线条的位置
            point = (
                random.randrange(0, self.img_width * 0.2),
                random.randrange(0, self.img_height),
                random.randrange(self.img_width - self.img_width * 0.2, self.img_width),
                random.randrange(0, self.img_height))
            # 线条的宽度
            width = random.randrange(1, 4)
            draw.line(point, fill=line_color, width=width)

        # 画验证码
        # 随机验证码严肃
        code_color = random.choice(font_color)
        # 指定验证码字体以及大小
        font = ImageFont.truetype(font_path, 15)
        # 画验证码
        # 画验证码
        for index, char in enumerate(code):
            code_color = random.choice(font_color)
            # 指定字体
            font_size = random.randrange(15, 25)
            font = ImageFont.truetype(font_path, font_size)
            point = (index * self.img_width / self.code_len,
                     random.randrange(0, self.img_height / 3))
            draw.text(point, char, font=font, fill=code_color)

        buf = io.BytesIO()
        im.save(buf, 'gif')
        return HttpResponse(buf.getvalue(), 'image/gif')


    def _get_vcode(self):
        random_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'
        code = random.sample(list(random_str), self.code_len)
        code = ''.join(code)
        return code

    def validate_code(self, code):
        '''验证验证码是否正确'''
        # 1. 转变大小写
        code = str(code).lower()
        vcode = self.dj_request.session.get(self.session_key, '')
        return vcode.lower() == code


if __name__ == '__main__':
    client = VerifyCode(None)
    client.gen_code()
